﻿//-----------------------------------------------------------------------
// <copyright file="SearchPanel.cs" company="In The Hand Ltd">
//     Copyright © 2013-14 In The Hand Ltd. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
#if WINDOWS_PHONE
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Resources;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
#else
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media.Animation;
using Windows.ApplicationModel.Resources;
using Windows.UI.Core;
using Windows.UI.Xaml.Input;
#endif

namespace InTheHand.ApplicationModel.Search
{
    internal sealed partial class SearchPanel : UserControl
    {
        private SearchPaneSuggestionsRequest request;
        private Storyboard hideStoryboard;

        public SearchPanel()
        {
            this.InitializeComponent();

            hideStoryboard = (Storyboard)this.Resources["Hide"];
            hideStoryboard.Completed += hideStoryboard_Completed;
            this.Loaded += SearchPanel_Loaded;
            SearchBox.KeyUp += SearchBox_KeyUp;
            SearchBox.TextChanged += SearchBox_TextChanged;

            // set layout for RTL languages
            switch (System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName)
            {
                case "ar":
                case "fa":
                case "he":
                    this.FlowDirection = FlowDirection.RightToLeft;
                    break;

                default:
                    this.FlowDirection = FlowDirection.LeftToRight;
                    break;
            }

            request = new SearchPaneSuggestionsRequest();
#if WINDOWS_PHONE
            SearchBox.Hint = InTheHand.ApplicationModel.Search.Resources.Resources.Search.ToLower();
#else
            
            SearchBox.PlaceholderText = ResourceLoader.GetForViewIndependentUse("InTheHand.ApplicationModel.Search/Resources").GetString("Search").ToLower();
#endif

#if WINDOWS_PHONE
            if (InTheHand.ApplicationModel.Package.Current.Capabilities.HasFlag(InTheHand.ApplicationModel.Capability.SpeechRecognition) && InTheHand.ApplicationModel.Package.Current.DeviceCapabilities.HasFlag(DeviceCapability.Microphone))
#else
            if(InTheHand.ApplicationModel.Package.Current.DeviceCapabilities.HasFlag(InTheHand.ApplicationModel.DeviceCapability.Microphone))
#endif
            {
                ConfigureSpeechActionIcon();
            }
        }

#if WINDOWS_PHONE
        void hideStoryboard_Completed(object sender, EventArgs e)
#else
        void hideStoryboard_Completed(object sender, object e)
#endif
        {
            Popup p = this.Parent as Popup;
            p.IsOpen = false;
        }


        // If supported add a microphone button to the search box
        private void ConfigureSpeechActionIcon()
        {
#if WINDOWS_PHONE
            if (Windows.Phone.Speech.Recognition.InstalledSpeechRecognizers.Default != null)
#else
            if(Windows.Media.SpeechRecognition.SpeechRecognizer.SystemSpeechLanguage != null)
#endif
            {
#if WINDOWS_PHONE
                StreamResourceInfo sri = Application.GetResourceStream(new Uri("InTheHand.ApplicationModel.Search;component/Microphone.png", UriKind.Relative));
                if (sri != null)
                {
                    BitmapImage micImage = new BitmapImage();
                    micImage.SetSource(sri.Stream);
                    SearchBox.ActionIcon = micImage;
                    SearchBox.ActionIconTapped += SearchBox_ActionIconTapped;
                }
#else
                ActionIcon.Visibility = Windows.UI.Xaml.Visibility.Visible;
#endif
            }
        }


        void SearchPanel_Loaded(object sender, RoutedEventArgs e)
        {
           
#if WINDOWS_PHONE
            PhoneApplicationFrame frame = (PhoneApplicationFrame)Application.Current.RootVisual;
            frame.OrientationChanged += frame_OrientationChanged;
#else
            Popup p = this.Parent as Popup;
            if(p != null)
            {
                p.LayoutUpdated += p_LayoutUpdated;
            }
#endif
        }

#if !WINDOWS_PHONE
        void p_LayoutUpdated(object sender, object e)
        {
            switch(Windows.Graphics.Display.DisplayInformation.GetForCurrentView().CurrentOrientation)
            {
                case Windows.Graphics.Display.DisplayOrientations.Landscape:
                    this.Margin = new Thickness(40, 0, 60, 0);
                    this.Width = Window.Current.CoreWindow.Bounds.Width - 100;
                    break;

                case Windows.Graphics.Display.DisplayOrientations.LandscapeFlipped:
                    this.Margin = new Thickness(60, 0, 40, 0);
                    this.Width = Window.Current.CoreWindow.Bounds.Width - 100;
                    break;

                case Windows.Graphics.Display.DisplayOrientations.Portrait:
                    this.Margin = new Thickness(0, 0, 0, 0);
                    this.Width = Window.Current.CoreWindow.Bounds.Width; 
                    break;
            }          
        }
#endif

#if WINDOWS_PHONE
        void frame_OrientationChanged(object sender, OrientationChangedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(string.Format("Orientation: {0}", e.Orientation));
            Microsoft.Phone.Controls.PhoneApplicationFrame frame = (Microsoft.Phone.Controls.PhoneApplicationFrame)Application.Current.RootVisual;

            // 72 pixels is the height of the applicationbar - no way to retrieve this programmatically is documented...
            switch (e.Orientation)
            {
                case PageOrientation.LandscapeLeft:
                    SearchPane.GetForCurrentView().Popup.Width = frame.RenderSize.Height - 144;
                    this.RenderTransform = new CompositeTransform() { Rotation = 90, TranslateX = (this.FlowDirection == System.Windows.FlowDirection.LeftToRight) ? frame.RenderSize.Width : 0 - frame.RenderSize.Width, TranslateY = 72 };
                    break;
                case PageOrientation.LandscapeRight:
                    SearchPane.GetForCurrentView().Popup.Width = frame.RenderSize.Height - 144;
                    this.RenderTransform = new CompositeTransform() { Rotation = -90, TranslateY = frame.RenderSize.Height - 72 };
                    break;
                default:
                    SearchPane.GetForCurrentView().Popup.Width = frame.RenderSize.Width;
                    this.RenderTransform = new CompositeTransform() { TranslateX = (this.FlowDirection == System.Windows.FlowDirection.LeftToRight) ? 0 : 0 - frame.RenderSize.Width };
                    break;
            }

            this.Width = SearchPane.GetForCurrentView().Popup.Width;
        }

#endif

#if WINDOWS_PHONE
        async void SearchBox_ActionIconTapped(object sender, EventArgs e)
#else
        async void SearchBox_ActionIconTapped(object sender, RoutedEventArgs e)
#endif
        {
            try
            {
#if WINDOWS_PHONE
                Windows.Phone.Speech.Recognition.SpeechRecognizerUI srUI = new Windows.Phone.Speech.Recognition.SpeechRecognizerUI();
                srUI.Settings.ShowConfirmation = false;
                Windows.Phone.Speech.Recognition.SpeechRecognitionUIResult result = await srUI.RecognizeWithUIAsync();
                if (result.ResultStatus == Windows.Phone.Speech.Recognition.SpeechRecognitionUIStatus.Succeeded)
                {
                    // recognition appends a full stop so remove it
                    SearchBox.Text = result.RecognitionResult.Text.TrimEnd('.');
                    InTheHand.ApplicationModel.Search.SearchPane.GetForCurrentView().OnQuerySubmitted(new SearchPaneQuerySubmittedEventArgs(SearchBox.Text));
                    hideStoryboard.Begin();
                }
#else
                Windows.Media.SpeechRecognition.SpeechRecognizer sr = new Windows.Media.SpeechRecognition.SpeechRecognizer();
                sr.Constraints.Add(new Windows.Media.SpeechRecognition.SpeechRecognitionTopicConstraint(Windows.Media.SpeechRecognition.SpeechRecognitionScenario.WebSearch, "search"));
                await sr.CompileConstraintsAsync();
                sr.UIOptions.ShowConfirmation = false;
                sr.UIOptions.IsReadBackEnabled = false;
                Windows.Media.SpeechRecognition.SpeechRecognitionResult result = await sr.RecognizeWithUIAsync();
                if(result.Status == Windows.Media.SpeechRecognition.SpeechRecognitionResultStatus.Success)
                {
                    SearchBox.Text = result.Text.TrimEnd('.');
                    InTheHand.ApplicationModel.Search.SearchPane.GetForCurrentView().OnQuerySubmitted(new SearchPaneQuerySubmittedEventArgs(SearchBox.Text));
                    hideStoryboard.Begin();
                }
#endif
            }
            catch(Exception ex)
            {
                // no active recogniser remove the icon
#if WINDOWS_PHONE
                SearchBox.ActionIcon = null;
                SearchBox.ActionIconTapped -= SearchBox_ActionIconTapped;
#else
                ActionIcon.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
#endif
            }
        }

        void SearchBox_TextChanged(object sender, RoutedEventArgs e)
        {
            //request.SearchSuggestionCollection.Clear();
            InTheHand.ApplicationModel.Search.SearchPane.GetForCurrentView().OnQueryChanged(new SearchPaneQueryChangedEventArgs(SearchBox.Text));
            //InTheHand.ApplicationModel.Search.SearchPane.GetForCurrentView().OnSuggestionsRequested(new SearchPaneSuggestionsRequestedEventArgs(SearchBox.Text, request));
            //if (request.SearchSuggestionCollection.Size > 0)
            //{
                //SearchBox.IsDropDownOpen = true;
            //}
        }

#if WINDOWS_PHONE
        void SearchBox_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
#else
        void SearchBox_KeyUp(object sender, KeyRoutedEventArgs e)
        {
            if (e.Key == Windows.System.VirtualKey.Enter)
#endif
            {
                InTheHand.ApplicationModel.Search.SearchPane.GetForCurrentView().OnQuerySubmitted(new SearchPaneQuerySubmittedEventArgs(SearchBox.Text));

                hideStoryboard.Begin();
            }
        }

        internal void SetFocus()
        {
#if WINDOWS_PHONE
            SearchBox.Focus();
#else
            SearchBox.Focus(Windows.UI.Xaml.FocusState.Programmatic);
#endif
        }

        private void SearchBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                SearchBox.Text = e.AddedItems[0].ToString();
            }
        }
    }
}
